package _40_设计模式._装饰器模式01;

/**
 * 装饰器模式要实现的类
 * Component                Coffee
 * AConcreteComponent       Latte
 * BConcreteComponent       BlockCoffee
 * Decorator                Decorator
 * AConcreteDecorator       MilkDecorator
 * BConcreteDecorator       SugarDecorator
 */

// Component: 被装饰者接口
interface Coffee {
    void createCoffee();
}

// AConcreteComponent: 被装饰者的具体实现类 黑咖啡
class BlackCoffee implements Coffee {
    @Override
    public void createCoffee() {
        System.out.println("create black coffee");
    }
}

// BConcreteComponent: 被装饰者的具体实现类 拿铁咖啡
class Latte implements Coffee {
    @Override
    public void createCoffee() {
        System.out.println("create latte coffee");
    }
}


// Decorator: 装饰器抽象类
abstract class Decorator implements Coffee {
    // 让子类可以访问到 被装饰者
    protected Coffee coffee;

    public Decorator(Coffee coffee) {
        this.coffee = coffee;
    }

    @Override
    public void createCoffee() {
        coffee.createCoffee();
    }
}

// AConcreteDecorator: 装饰器具体实现类 加牛奶装饰
class MilkDecorator extends Decorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public void createCoffee() {
        // 在原方法之前 做装饰
        washCup();
        // 执行原方法
        coffee.createCoffee();
        // 在原方法之后做装饰
        addMilk(coffee);
    }

    // 装饰功能：洗杯子
    public void washCup() {
        System.out.println("洗杯子");
    }

    // 装饰功能：加牛奶
    public void addMilk(Coffee coffee) {
        System.out.println("加入牛奶");
    }
}

// BConcreteDecorator: 装饰器具体实现类 加糖装饰
class SugarDecorator extends Decorator {
    public SugarDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public void createCoffee() {
        coffee.createCoffee();
        addSugar(coffee);
    }

    public void addSugar(Coffee coffee) {
        System.out.println("加入一些糖");
    }
}

public class DecoratorTest01 {
    public static void main(String[] args) {
        BlackCoffee blackCoffee = new BlackCoffee();
        SugarDecorator sugarDecorator = new SugarDecorator(blackCoffee);
        sugarDecorator.createCoffee();
    }
}

